/***********************************************************************
*
* Copyright (c) 2012-2020 Barbara Geller
* Copyright (c) 2012-2020 Ansel Sermersheim
*
* Copyright (c) 2015 The Qt Company Ltd.
* Copyright (c) 2012-2016 Digia Plc and/or its subsidiary(-ies).
* Copyright (c) 2008-2012 Nokia Corporation and/or its subsidiary(-ies).
*
* This file is part of CopperSpice.
*
* CopperSpice is free software. You can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* CopperSpice is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* https://www.gnu.org/licenses/
*
***********************************************************************/

#ifndef QResourceLoader_P_H
#define QResourceLoader_P_H

#include "qitem_p.h"
#include "qreportcontext_p.h"
#include "qsequencetype_p.h"
#include "qsourcelocationreflection_p.h"

QT_BEGIN_NAMESPACE

class QUrl;

namespace QPatternist {
class ResourceLoader : public QSharedData
{
 public:
   enum Usage {
      /**
       * Communicates that the URI may be used during query evaluation.
       * For example, zero times or very many times.
       *
       * Typically this hint is given when the URI is available at
       * compile-time, but it is used inside a conditional statement
       * whose branching cannot be determined at compile time.
       */
      MayUse,

      /**
       * Communicates that the URI will always be used at query
       * evaluation.
       */
      WillUse
   };

   typedef QExplicitlySharedDataPointer<ResourceLoader> Ptr;
   inline ResourceLoader() {}
   virtual ~ResourceLoader();

   /**
    * @short Calls to this function are generated by calls to the
    * <tt>fn:unparsed-text-available()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @returns @c true if calling openUnparsedText() while passing @p uri will successfully load
    * the document.
    * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
    * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
    */
   virtual bool isUnparsedTextAvailable(const QUrl &uri,
                                        const QString &encoding);

   /**
    * @short May be called by the compilation framework at compile time to report that an
    * unparsed text(plain text) file referenced by @p uri will be loaded at runtime.
    *
    * This function can be called an arbitrary amount of times for the same URI. How many times
    * it is called for a URI has no meaning(beyond the first call, that is). For what queries
    * the compilation framework can determine what always will be loaded is generally undefined. It
    * depends on factors such as how simple the query is what information that is statically
    * available and subsequently what optimizations that can apply.
    *
    * Calls to this function are generated by calls to the <tt>fn:unparsed-text()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
    * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
    * @returns
    * - @c null if no unparsed file can be loaded for @p uri
    * - The item type that the value loaded by @p uri will be an instance of. This is
    *   typically @c xs:string
    */
   virtual ItemType::Ptr announceUnparsedText(const QUrl &uri);

   /**
    * @short Calls to this function are generated by calls to the <tt>fn:unparsed-text()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @param encoding the encoding to use. If empty, the user hasn't
    * expressed any encoding to use.
    * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
    * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
    * @returns
    * - @c null if no unparsed file can be loaded for @p uri
    * - An @c xs:string value(or subtype) containing the content of the file identified
    *   by @p uri as text. Remember that its type must  match the sequence type
    *   returned by announceUnparsedText()
    */
   virtual Item openUnparsedText(const QUrl &uri,
                                 const QString &encoding,
                                 const ReportContext::Ptr &context,
                                 const SourceLocationReflection *const where);

   /**
    * @short Calls to this function are generated by calls to the <tt>fn:document()</tt>
    * or <tt>fn:doc()</tt> function.
    *
    * @note This function is responsible for execution stability. Subsequent calls
    * to this function with the same URI should result in QXmlNodeModelIndex instances that have
    * the same identity. However, in some cases this stability is not of interest, see
    * the specification for details.
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @see QXmlNodeModelIndex::identity()
    * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc">XQuery 1.0
    * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc</a>
    * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
    * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
    * @returns
    * - @c null if no document can be loaded for @p uri
    * - A QXmlNodeModelIndex representing the document identified by @p uri. Remember that the QXmlNodeModelIndex
    *   must match the sequence type returned by announceDocument()
    */
   virtual Item openDocument(const QUrl &uri,
                             const ReportContext::Ptr &context);

   /**
    * @short May be called by the compilation framework at compile time to report that an
    * XML document referenced by @p uri will be loaded at runtime.
    *
    * This function can be called an arbitrary amount of times for the same URI, but different
    * @p usageHint values. How many times it is called for a URI has no meaning(beyond the first call,
    * that is). For what queries the compilation framework can determine what always will be
    * loaded is generally undefined. It
    * depends on factors such as the complexity of the query, what information that is statically
    * available and subsequently what optimizations that can be applied.
    *
    * Calls to this function are generated by calls to the <tt>fn:document()</tt>
    * or <tt>fn:doc()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @param usageHint A hint to how the URI will be used.
    * @returns
    *  - @c null if the ResourceLoader can determine at this stage that no document
    *  referenced by @p uri will ever be possible to load.
    *  - The appropriate sequence type if loading @p uri succeeds at runtime. This must be
    *  CommonSequenceTypes::zeroOrOneDocument, CommonSequenceTypes::exactlyOneDocument or
    *  a sequence type that is a sub type of it.
    * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc">XQuery 1.0
    * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc</a>
    * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
    * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
    */
   virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint);

   /**
    * @short Calls to this function are generated by calls to the <tt>fn:doc-available()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @returns @c true if calling openDocument() while passing @p uri will successfully load
    * the document.
    * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc-available">XQuery 1.0
    * and XPath 2.0 Functions and Operators, 15.5.5 fn:doc-available</a>
    * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
    * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
    */
   virtual bool isDocumentAvailable(const QUrl &uri);

   /**
    * @short Calls to this function are generated by calls to the <tt>fn:collection()</tt> function.
    *
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @see <a href="http://www.w3.org/TR/xpath-functions/#func-collection">XQuery 1.0
    * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection</a>
    * @returns
    * - @c null if no node collection can be loaded for @p uri
    * - An QAbstractXmlForwardIterator representing the content identified by @p uri. Remember that the content
    *   of the QAbstractXmlForwardIterator must match the sequence type returned by announceCollection()
    */
   virtual Item::Iterator::Ptr openCollection(const QUrl &uri);

   /**
    * @short May be called by the compilation framework at compile time to report that an
    * node collection referenced by @p uri will be loaded at runtime.
    *
    * This function can be called an arbitrary amount of times for the same URI. How many times
    * it is called for a URI has no meaning(beyond the first call, that is). For what queries
    * the compilation framework can determine what always will be loaded is generally undefined. It
    * depends on factors such as how simple the query is what information that is statically
    * available and subsequently what optimizations that can apply.
    *
    * Calls to this function are generated by calls to the <tt>fn:collection()</tt> function.
    *
    * @note This function is responsible for execution stability. Subsequent calls
    * to this function with the same URI should result in QXmlNodeModelIndex instances that have
    * the same identity. However, in some cases this stability is not of interest, see
    * the specification for details.
    * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
    * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
    * returns @c false).
    * @returns
    *  - @c null if the ResourceLoader can determine at this stage that no document
    *  referenced by @p uri will ever be possible to load.
    *  - The appropriate sequence type if loading @p uri succeeds at runtime. This must be
    *  CommonSequenceTypes::zeroOrMoreNodes or a sequence type that is a sub type of it.
    * @see <a href="http://www.w3.org/TR/xpath-functions/#func-collection">XQuery 1.0
    * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection</a>
    */
   virtual SequenceType::Ptr announceCollection(const QUrl &uri);

   /**
    * @short Asks to unload @p uri from its document pool, such that a
    * subsequent request will require a new read.
    *
    * The default implementation does nothing.
    */
   virtual void clear(const QUrl &uri);
};
}

QT_END_NAMESPACE

#endif
